home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 46
/
Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso
/
-in_the_mag-
/
synth_studies
/
resgrep03b
/
source
/
export.cc
next >
Wrap
C/C++ Source or Header
|
1999-09-15
|
17KB
|
728 lines
//
// export.cc
//
// This file contain the functions for exporting data from ResGrep.
// Here are the bulidin-commands and the interface function to other, extern
// commands addressed via ARexx.
//
extern "C" {
#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <graphics/displayinfo.h>
#include <dos/dos.h>
#include <stdlib.h>
#include <math.h>
char *strdup(char *);
};
#include "id.h"
#include "export.h"
#include "resgrep.h"
#include "utils.h"
extern "C" {
#include <clib/iffparse_protos.h>
#include <clib/dos_protos.h>
};
#define ONE ((size_t)1)
exportfunc exportfunctions[4]=
{
convert::rawdata,
convert::text2ascii,
convert::text2ftxt,
convert::snd28svx
};
convert::convert(unsigned long theType,
int thefuncnum,
char *theName, char *theCommand, bool theIsARexx,
send theSendTo, char *theFilename,
bool thebuiltin)
: node(theName,nocopy,0,theType)
{
funcnum = thefuncnum;
command = strdup(theCommand);
isARexx = theIsARexx;
sendto = theSendTo;
filename= strdup(theFilename);
builtin = thebuiltin;
}
convert::~convert(void)
{
}
list *conversions;
void initexport(void)
{
conversions = new list();
conversions->addtail(
new convert(ID_ICNd,4,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_ICNd,0,"raw data",
NULL,false,File,"T:IconOut"));
conversions->addtail(
new convert(ID_STRd,2,"IFF-FTXT",
NULL,false,Clipboard));
conversions->addtail(
new convert(ID_STRd,0,"raw data",
NULL,false,File,"T:TextOut"));
conversions->addtail(
new convert(ID_STRd,1,"plain ASCII",
NULL,false,File,"T:TextOut"));
conversions->addtail(
new convert(ID_snd,3,"IFF-8SVX",
NULL,false,File,"T:SoundOut"));
conversions->addtail(
new convert(ID_snd,0,"raw data",
NULL,false,File,"T:SoundOut"));
conversions->addtail(
new convert(ID_icl4,5,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_icl4,0,"raw data",
NULL,false,File,"T:IconOut"));
conversions->addtail(
new convert(ID_icl8,6,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_icl8,0,"raw data",
NULL,false,File,"T:IconOut"));
conversions->addtail(
new convert(ID_icsd,7,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_icsd,0,"raw data",
NULL,false,File,"T:IconOut"));
conversions->addtail(
new convert(ID_ics4,8,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_ics4,0,"raw data",
NULL,false,File,"T:IconOut"));
conversions->addtail(
new convert(ID_ics8,9,"IFF-ILBM",
NULL,false,Clipboard,"T:IconOut"));
conversions->addtail(
new convert(ID_ics8,0,"raw data",
NULL,false,File,"T:IconOut"));
}
int convert::getfuncnum(void)
{
return funcnum;
}
int exportres(unsigned long theType, FILE *fp, unsigned long DataOffset)
{
node *n;
convert *c;
int ret;
if( (n=conversions->findpack(theType)) == NULL )
return ERR_NO_CONVERS;
c=(convert *)n;
switch( c->getfuncnum() )
{
case 0:
ret=c->rawdata(fp,DataOffset);
break;
case 1:
ret=c->text2ascii(fp,DataOffset);
break;
case 2:
ret=c->text2ftxt(fp,DataOffset);
break;
case 3:
ret=c->snd28svx(fp,DataOffset);
break;
case 4:
ret=c->ICNd2ilbm(fp,DataOffset);
break;
case 5:
ret=c->icl42ilbm(fp,DataOffset);
break;
case 6:
ret=c->icl82ilbm(fp,DataOffset);
break;
case 7:
ret=c->icsd2ilbm(fp,DataOffset);
break;
case 8:
ret=c->ics42ilbm(fp,DataOffset);
break;
case 9:
ret=c->ics82ilbm(fp,DataOffset);
break;
default:
ResError("Fatal:\nUnknown function detected\nduring data export.");
break;
}
c->docommand();
return ret;
}
void convert::docommand(void)
{
if( isARexx )
{
ResWarning("Sorry!\nARexx Port not implemented yet.\n");
return;
}
system(command);
}
//------------------------------------ all ---
char *buffer=NULL;
unsigned long bufferlen;
int readdata(FILE *fp, unsigned long offset)
{
if( buffer!=NULL )
free(buffer);
buffer=NULL;
bufferlen=0;
rewind(fp);
if( fseek(fp,offset,SEEK_SET)!=0 )
return ERR_FILE_CORRUPTED;
if( fread((void *)&bufferlen,sizeof(unsigned long),ONE,fp)!=ONE )
return ERR_FILE_CORRUPTED;
if( (buffer=(char *)malloc(bufferlen))==NULL )
return ERR_NO_MEMORY;
if( fread((void *)buffer,sizeof(char),bufferlen,fp)!=bufferlen )
{
free(buffer);
buffer=NULL;
return ERR_FILE_CORRUPTED;
}
return ERR_NO;
}
//------------------------------------ RawData
int convert::rawdata(FILE *fp, unsigned long DataOffset)
{
int ret;
FILE *out;
if( sendto!=File )
{
ResError("It's stricly forbidden to\nwrite non-iff files\n"
"to the clipboard");
return 1;
}
if( (ret=readdata(fp,DataOffset))!=ERR_NO )
return ret;
if( (out=fopen(filename,"w"))==NULL )
return ERR_FILE_OPEN;
fwrite(buffer,sizeof(char),bufferlen,out);
fclose(out);
return ERR_NO;
}
//------------------------------------ STR#
int convert::text2ascii(FILE *fp, unsigned long DataOffset)
{
int ret;
unsigned short *StrNum;
unsigned char *StrLen;
char *buf;
int index;
if( (ret=readdata(fp,DataOffset))!=ERR_NO )
return ret;
if( sendto==File )
{
FILE *out;
if( (out=fopen(filename,"w"))==NULL )
return ERR_FILE_OPEN;
StrNum = (unsigned short *)buffer;
buf=buffer+sizeof(unsigned short);
// Einmal über alle Strings
for(index=0;
index < (int)(*StrNum);
index++)
{
StrLen = (unsigned char *)buf++;
if( fwrite(buf,sizeof(unsigned char),(size_t)(*StrLen),out)
!= (size_t)(*StrLen) )
{
fclose(out);
return ERR_WRITE;
}
buf+= *StrLen;
fprintf(out,"\n");
}
fclose(out);
}
return ERR_NO;
}
int convert::text2ftxt(FILE *fp, unsigned long DataOffset)
{
int ret;
unsigned short *StrNum;
unsigned char *StrLen;
char *buf;
struct IFFHandle *iff;
char newline='\n';
if( (ret=readdata(fp,DataOffset))!=ERR_NO )
return ret;
if( (iff=AllocIFF())==NULL )
return ERR_NO_MEMORY;
if( sendto==Clipboard )
{
if( (iff->iff_Stream=(ULONG)OpenClipboard(0))==NULL )
{
FreeIFF(iff);
return ERR_NO_CLIPBOARD;
}
InitIFFasClip(iff);
}
else if( sendto=File )
{
if( (iff->iff_Stream=(ULONG)Open((UBYTE *)filename,MODE_NEWFILE))==NULL )
{
FreeIFF(iff);
return ERR_NO_FILE;
}
InitIFFasDOS(iff);
}
if( OpenIFF(iff,IFFF_WRITE)!=0 )
{
ResError("Error occured during 'OpenIFF()'.");
return ERR_OPENIFF;
}
if( (ret=PushChunk(iff,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))!=0 )
{
ResError("Error while writing the\n'FORM' chunk.");
return ERR_WRITE;
}
if( (ret=PushChunk(iff,ID_FTXT,ID_CHRS,IFFSIZE_UNKNOWN))!=0 )
{
ResError("Error while writing the\n'FTXT' chunk.");
return ERR_WRITE;
}
StrNum = (unsigned short *)buffer;
buf=buffer+sizeof(unsigned short);
// Einmal über alle Strings
for(int index=0; index <(int)(*StrNum); index++)
{
StrLen = (unsigned char *)buf++;
if( WriteChunkBytes(iff,(UBYTE *)buf,(LONG)*StrLen)!=(LONG)*StrLen )
return ERR_WRITE;
buf+= *StrLen;
WriteChunkBytes(iff,&newline,1);
}
if( PopChunk(iff)!=0 ) // pop the CHRS
{
ResError("Error while poping the\n'CHRS' chunk.");
return 1;
}
if( PopChunk(iff)!=0 ) // pop the FORM
{
ResError("Error while poping the\n'FORM' chunk.");
return 1;
}
CloseIFF(iff);
if( sendto==Clipboard )
CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
else if( sendto==File )
{
Close((BPTR)iff->iff_Stream);
}
FreeIFF(iff);
return ERR_NO;
}
// ---------------------------------------------- snd
// This is only a minimal version. It greps the first
// digitizes sound.
int convert::snd28svx(FILE *fp, unsigned long DataOffset)
{
int ret, index;
unsigned short *SndType;
unsigned short *NumberOfCommands, *cmd;
char *buf;
char *BegOfSound;
struct IFFHandle *iff;
struct VoiceHeader // Ami
{
unsigned long NumSamples;
unsigned long NumRepeatSamples;
unsigned long NumRepeats;
unsigned short SampleRate;
unsigned char NumOct;
unsigned char Compression;
unsigned long Volume;
} vh;
struct SoundHeader // Mac
{
unsigned long samplePrt;
unsigned long length;
unsigned long sampleRate;
unsigned long loopStart;
unsigned long loopEnd;
unsigned short priv;
char sampleArea[1];
} *sh;
// unsigned long encode;
// unsigned long baseFrequency;
if( (ret=readdata(fp,DataOffset))!=ERR_NO )
return ret;
buf=buffer;
// Dann erst einmal die Daten suchen (vielleicht gibt es ja gar nichts
// digitalisiertes.)
SndType=(unsigned short *)buf;
buf+=sizeof(short);
if( *SndType!=0x0001 )
{
ResError("Mac snd type is not '0x0001'.");
return ERR_NO_MEMORY; // ???
}
// Skip Modifiers
NumberOfCommands=(unsigned short *)buf;
buf+=sizeof(short);
// Skip them
buf+=6* *NumberOfCommands;
// Parse Commands
NumberOfCommands=(unsigned short *)buf;
buf+=sizeof(short);
for(index=0; index< *NumberOfCommands; index++)
{
cmd=(unsigned short *)buf;
if( (*cmd & 0x7FFF) == 81 )
break;
buf+=8;
}
if( (*cmd & 0x7FFF) != 81 )
return ERR_NO_MEMORY;
sh=(struct SoundHeader *) ( buffer + *( (unsigned long *)(buf+4) ) );
BegOfSound = &(sh->sampleArea[0]);
for(index=0; index<sh->length; index++)
*(BegOfSound+index) ^= 0x80;
if( (iff=AllocIFF())==NULL )
return ERR_NO_MEMORY;
if( sendto==Clipboard )
{
if( (iff->iff_Stream=(ULONG)OpenClipboard(0))==NULL )
{
FreeIFF(iff);
return ERR_NO_CLIPBOARD;
}
InitIFFasClip(iff);
}
else if( sendto=File )
{
if( (iff->iff_Stream=(ULONG)Open((UBYTE *)filename,MODE_NEWFILE))==NULL )
{
FreeIFF(iff);
return ERR_NO_FILE;
}
InitIFFasDOS(iff);
}
if( OpenIFF(iff,IFFF_WRITE)!=0 )
{
ResError("Error occured during 'OpenIFF()'.");
return ERR_OPENIFF;
}
if( (ret=PushChunk(iff,ID_8SVX,ID_FORM,IFFSIZE_UNKNOWN))!=0 )
{
ResError("Error while writing the\n'FORM' chunk.");
return ERR_WRITE;
}
if( (ret=PushChunk(iff,ID_8SVX,ID_VHDR,sizeof(struct VoiceHeader)))!=0 )
{
ResError("Error while writing the\n'VHDR' chunk.");
return ERR_WRITE;
}
// Schreiben des VHDR
vh.NumSamples = sh->length;
vh.NumRepeatSamples = 0;
vh.NumRepeats = 0;
vh.SampleRate = (short) (sh->sampleRate / 65536);
vh.NumOct = 1;
vh.Compression = 0;
vh.Volume = (unsigned long) (64 * 65536);
if( WriteChunkBytes(iff,(UBYTE *)&vh,sizeof(struct VoiceHeader))
!=sizeof(struct VoiceHeader) )
return ERR_WRITE;
if( PopChunk(iff)!=0 ) // pop the VHDR
{
ResError("Error while poping the\n'VHDR' chunk.");
return 1;
}
if( (ret=PushChunk(iff,ID_8SVX,ID_BODY,sh->length))!=0 )
{
printf("BODY: Fehler beim schreiben der Daten (%4d).\n",ret);
return ERR_WRITE;
}
if( WriteChunkBytes(iff,(UBYTE *)BegOfSound,sh->length)!=sh->length )
return ERR_WRITE;
if( PopChunk(iff)!=0 ) // pop the BODY
{
ResError("Error while poping\n'BODY' chunk.");
return 1;
}
if( PopChunk(iff)!=0 ) // pop the FORM
{
ResError("Error while poping\n'FORM' chunk.");
return 1;
}
CloseIFF(iff);
if( sendto==Clipboard )
CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
else if( sendto==File )
{
Close((BPTR)iff->iff_Stream);
}
FreeIFF(iff);
return ERR_NO;
}
// ------------------------------------------------------ ICONS
int convert::ICNd2ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,32,32,1);
}
int convert::icl42ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,32,32,4);
}
int convert::icl82ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,32,32,8);
}
int convert::icsd2ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,16,16,1);
}
int convert::ics42ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,16,16,4);
}
int convert::ics82ilbm(FILE *fp, unsigned long DataOffset)
{
return icons2ilbm(fp,DataOffset,16,16,8);
}
int convert::icons2ilbm(FILE *fp, unsigned long DataOffset,
unsigned long x, unsigned long y,
unsigned long ftiefe)
{
unsigned char **planes;
int index, pixel, offset, zeile;
int ret;
struct IFFHandle *iff;
// Amiga BitMapHeader
struct BitMapHeader
{
unsigned short width;
unsigned short height;
short xpos;
short ypos;
unsigned char numplanes;
unsigned char mask;
unsigned char compression;
unsigned char privat;
unsigned short transp;
unsigned char xsize;
unsigned char ysize;
short ux;
short uy;
} bmh;
if( x%8!=0 ) // X muss ein Vielfaches von 8 sein
return 1;
if( (ret=readdata(fp,DataOffset))!=ERR_NO )
return ret;
if( (planes=(unsigned char **)malloc(ftiefe*sizeof(unsigned char *)))
==NULL)
return 2;
for(index=0; index<ftiefe; index++)
if( (planes[index]=(unsigned char *)
calloc(x*y/8,sizeof(unsigned char)))==NULL )
return 3;
// Für jede Bitplane
for(offset=0; offset<ftiefe; offset++)
for(pixel=offset, index=0; pixel<x*y*ftiefe; pixel+=ftiefe, index++)
if( GETBIT(buffer,pixel)==1 )
SETBIT(planes[offset],index);
if( (iff=AllocIFF())==NULL )
return ERR_NO_MEMORY;
if( sendto==Clipboard )
{
if( (iff->iff_Stream=(ULONG)OpenClipboard(0))==NULL )
{
FreeIFF(iff);
return ERR_NO_CLIPBOARD;
}
InitIFFasClip(iff);
}
else if( sendto=File )
{
if( (iff->iff_Stream=(ULONG)Open((UBYTE *)filename,MODE_NEWFILE))==NULL )
{
FreeIFF(iff);
return ERR_NO_FILE;
}
InitIFFasDOS(iff);
}
if( OpenIFF(iff,IFFF_WRITE)!=0 )
{
ResError("Error occured during 'OpenIFF()'.");
return ERR_OPENIFF;
}
if( (ret=PushChunk(iff,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN))!=0 )
{
ResError("Error while writing the\n'FORM' chunk.");
return ERR_WRITE;
}
if( (ret=PushChunk(iff,ID_ILBM,ID_BMHD,sizeof(struct BitMapHeader)))!=0 )
{
ResError("Error while writing the\n'BMHD' chunk.");
return ERR_WRITE;
}
// Schreiben des BMH
bmh.width = x;
bmh.height = y;
bmh.xpos = 0;
bmh.ypos = 0;
bmh.numplanes = ftiefe;
bmh.mask = 0;
bmh.compression = 0;
bmh.privat = 0;
bmh.transp = 0;
bmh.xsize = 1;
bmh.ysize = 1;
bmh.ux = x;
bmh.uy = y;
if( WriteChunkBytes(iff,(UBYTE *)&bmh,sizeof(struct BitMapHeader))
!=sizeof(struct BitMapHeader) )
return ERR_WRITE;
if( PopChunk(iff)!=0 ) // pop the BMHD
{
ResError("Error while poping the\n'BMHD' chunk.");
return 1;
}
if( (ret=PushChunk(iff,ID_ILBM,ID_BODY,x*y/8*ftiefe))!=0 )
{
printf("BODY: Fehler beim schreiben der Daten (%4d).\n",ret);
return ERR_WRITE;
}
//printf("Schreibe ILBM-BODY\n");
// Schreiben des ILBM
for(zeile=0; zeile<y; zeile++)
for(index=0; index<ftiefe; index++)
if( WriteChunkBytes(iff,(UBYTE *)planes[index]+x/8*zeile,x/8)!=x/8 )
return ERR_WRITE;
//printf("Fertig mit schreiben des ILBM-BODY\n");
if( PopChunk(iff)!=0 ) // pop the BODY
{
ResError("Error while poping\n'BODY' chunk.");
return 1;
}
if( PopChunk(iff)!=0 ) // pop the FORM
{
ResError("Error while poping\n'FORM' chunk.");
return 1;
}
CloseIFF(iff);
if( sendto==Clipboard )
CloseClipboard((struct ClipboardHandle *)iff->iff_Stream);
else if( sendto==File )
{
Close((BPTR)iff->iff_Stream);
}
FreeIFF(iff);
for(index=0; index<ftiefe; index++)
free(planes[index]);
free(planes);
return ERR_NO;
}